import React from "react";
import { renderToString } from "react-dom/server"; // 前端组件转字符串
import { StaticRouter } from "react-router"; // 服务器端路由
import proxy from "express-http-proxy"; // 代理接口
import App from "../App";
import { getServerStore } from "../store"; //服务端redux数据
import { matchRoutes } from "react-router-dom"; // 获取路由信息
import routerConfig from "../routerConfig"; // 路由配置
const express = require("express");

const app = express();
app.use(express.static("public")); //   静态资源StStaticRouter>
app.use(
  "/api",
  proxy("http://localhost:3009", {
    proxyReqPathResolver: function (req) {
      console.log(req.url, "req.url");
      return req.url;
    },
  })
);
app.get("*", (req, res) => {
  const matchedRoutes = matchRoutes(routerConfig, { pathname: req.url }); // 获取路由信息

  console.log(matchedRoutes,routerConfig, "matchedRoutes");
  if (matchedRoutes) {
    const store = getServerStore(); // 获取服务端redux数据
    /*
     * 获取loadData方法
     * 因为我们本次渲染可能会走多个数据加载方式，进行多次接口调用，可能有些成功了，有些失败了，
     * 默认情况下，如果一个接口失败了，整个应用加载失败，所以我们要不管成功还是失败都变成成功
     */
    const loadDataPromises = matchedRoutes
      .map((matched) => {
        const { loadData } = matched.route.element.type;
        // console.log(loadData, matched.route.element.type, "loadData");
        if (loadData) {
          return loadData(store).then(
            (data) => data,
            (error) => error
          );
        }
      })
      .filter(Boolean);
    // console.log(loadDataPromises, "loadDataPromises");
    Promise.all(loadDataPromises).then((allres) => {
      console.log(allres, "all");
      const html = renderToString(
        <StaticRouter location={req.url}>
          <App store={store}></App>
        </StaticRouter>
      );
      // console.log(html,req.url,'html')
      res.send(`
        <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="root">${html}</div>
        <script >
        // 服务端和浏览器 分别是两个store  为了 服务端和客户端store同步.
        // 这里 context必须用var声明，因为context是全局变量，否则会报错
         var context = {
          store: ${JSON.stringify(store.getState())}
         };
        </script>
        <script src="/client.js"></script>
    </body>
    </html>
        
        `);
    });
  } else {
    res.send("404");
  }
});

app.listen(3008, () => {});
